package com.usefullc.chatgpt.filter;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import com.usefullc.chatgpt.constants.ChatgptConstants;
import com.usefullc.common.util.JsonUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.FilterConfig;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;


//@Configuration
//@Order(1)
//@WebFilter(filterName = "videoFilter", urlPatterns = {"/video/*"})
public class ChatgptFilter implements Filter {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    private ChatgptResourceHttpRequestHandler resourceHttpRequestHandler;

    public ChatgptFilter(ChatgptResourceHttpRequestHandler resourceHttpRequestHandler) {
        this.resourceHttpRequestHandler = resourceHttpRequestHandler;
    }

    private Map<String, String> pathMediaTypeMap = new HashMap<>();

    {
        pathMediaTypeMap.put("/api/auth/session", "json");
        pathMediaTypeMap.put("/backend-api/conversations", "json");
        pathMediaTypeMap.put("/messenger/web/ping", "json");
        pathMediaTypeMap.put("/v1/initialize", "json");
        pathMediaTypeMap.put("/v1/rgstr", "json");
        pathMediaTypeMap.put("/backend-api/models", "json");
    }

        private static String commonResData = "{\"code\":200,\"data\":null,\"msg\":\"操作成功\",\"page\":null}";
    private Map<String,ResponseBean> fateResponseDataMap = new HashMap<>();
    {

        ResponseBean responseBean = new ResponseBean();
        responseBean.setBody("");
        responseBean.getHeaderMap().put("Content-Type","text/plain; charset=UTF-8");
        fateResponseDataMap.put("/cdn-cgi/challenge-platform/h/g/cv/result/7dcbe5860b4af224",responseBean);

//        fateResponseDataMap.put("/User/SetPage","{\"code\":200,\"data\":{\"day\":300,\"yesterday\":1665,\"week\":6865,\"month\":12635,\"totalLearningTime\":12635,\"contiDay\":4,\"totalDay\":7,\"notice\":\"新增MP3学习资料（替换练习）\"},\"msg\":\"操作成功\",\"page\":null}");
//        fateResponseDataMap.put("/Sys/SysKey","{\"code\":200,\"data\":{\"syS-KEY-ESC-FULL\":\"esc\",\"syS-KEY-PLAY-PAUSE\":\"space\",\"syS-KEY-BACK\":\"<\",\"syS-KEY-FORWARD\":\">\",\"syS-KEY-ADD\":\"+\",\"syS-KEY-SUBTRACT\":\"-\",\"syS-KEY-NORMAL\":\"0\",\"syS-KEY-UP\":\"a \",\"syS-KEY-NEXT\":\"d\",\"syS-KEY-INSPIRE\":\"s\",\"syS-KEY-FUZZY\":\"b\",\"syS-KEY-CYCLE\":\"w\",\"syS-KEY-HIDDEN\":\"x\",\"syS-KEY-CUSTOM\":\"{ + }\",\"syS-KEY-NOTE\":\"n\",\"syS-KEY-VIDEO\":\"v\"},\"msg\":\"操作成功\",\"page\":null}");
//        fateResponseDataMap.put("/Sys/YouDaoHtml","{\"code\":200,\"data\":null,\"msg\":\"操作成功\",\"page\":null}");
//        fateResponseDataMap.put("/Video/AddPlayProcess","{\"code\":200,\"data\":null,\"msg\":\"操作成功\",\"page\":null}");
////        fateResponseDataMap.put("/Video/AddWord","{\"code\":200,\"data\":null,\"msg\":\"操作成功\",\"page\":null}");
//        fateResponseDataMap.put("/Note/","{\"code\":200,\"data\":null,\"msg\":\"操作成功\",\"page\":null}");
//        fateResponseDataMap.put("/User/","{\"code\":200,\"data\":null,\"msg\":\"操作成功\",\"page\":null}");
//        fateResponseDataMap.put("/Sys/","{\"code\":200,\"data\":{\"syS-KEY-ESC-FULL\":\"esc\",\"syS-KEY-PLAY-PAUSE\":\"space\",\"syS-KEY-BACK\":\"<\",\"syS-KEY-FORWARD\":\">\",\"syS-KEY-ADD\":\"+\",\"syS-KEY-SUBTRACT\":\"-\",\"syS-KEY-NORMAL\":\"0\",\"syS-KEY-UP\":\"a \",\"syS-KEY-NEXT\":\"d\",\"syS-KEY-INSPIRE\":\"s\",\"syS-KEY-FUZZY\":\"b\",\"syS-KEY-CYCLE\":\"w\",\"syS-KEY-HIDDEN\":\"x\",\"syS-KEY-CUSTOM\":\"{ + }\",\"syS-KEY-NOTE\":\"n\",\"syS-KEY-VIDEO\":\"v\"},\"msg\":\"操作成功\",\"page\":null}");
//        fateUrls.add("/Sys/");
    }


    private Map<String,String> rewritePathMap = new HashMap<>();
    {
//        rewritePathMap.put("/","/index.html");
        rewritePathMap.put("/index","/index.html");
//        rewritePathMap.put("/player","/index.html");
    }

    private Map<String,String> videoPathMap = new HashMap<>();
    private void initVideoPath(){
//        String dirs [] = new String[]{"/Users/long3/Downloads/huilianEnglish/"};
        String dirs [] = new String[]{ChatgptConstants.RESOURCE_DIR};
        for (String dir : dirs) {
            try{
                Collection<File> files = FileUtils.listFiles(new File(dir), new WildcardFileFilter("*.mp4*"), DirectoryFileFilter.INSTANCE);
                for (File file : files) {
                    String absolutePath = file.getAbsolutePath();
                    int index = absolutePath.indexOf("?");
                    String keyPath = absolutePath;
                    if(absolutePath.indexOf("?")  > 0){
                        keyPath = absolutePath.substring(0,index);
                    }
                    String path = "/"+StringUtils.remove(keyPath, dir);
                    videoPathMap.put(path,absolutePath);
                }
            }catch (Exception e){
                logger.error(e.getMessage());
            }
        }
    }


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        resourceHttpRequestHandler.addMatchPathUrls("/_next");
        resourceHttpRequestHandler.addMatchPathUrls("/api");
        resourceHttpRequestHandler.addMatchPathUrls("/backend-api");
        resourceHttpRequestHandler.addMatchPathUrls("/cdn-cgi");
        resourceHttpRequestHandler.addMatchPathUrls("/common");
        resourceHttpRequestHandler.addMatchPathUrls("/messenger");
        resourceHttpRequestHandler.addMatchPathUrls("/v1");
        resourceHttpRequestHandler.addMatchPathUrls("/widget");

        initVideoPath();


    }

    private String jsonToQuery(JSONObject jsonObject) {
        Set<String> set = jsonObject.keySet();
        Map<String, String> paramMap = new TreeMap<>();
        anlyseJsonToUrl(jsonObject, paramMap);

        String query = Joiner.on("&")
                // 用指定符号代替空值,key 或者value 为null都会被替换
                .useForNull("")
                .withKeyValueSeparator("=")
                .join(paramMap);
        return query;

    }


    private void anlyseJsonToUrl(JSONObject jsonObject, Map<String, String> paramMap) {
        Set<String> set = jsonObject.keySet();
        for (String key : set) {
            Object o = jsonObject.get(key);
            if (o instanceof JSONObject) {
                anlyseJsonToUrl(jsonObject.getJSONObject(key), paramMap);
            } else {
                paramMap.put(key, jsonObject.get(key).toString());
            }
        }
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String servletPath = httpRequest.getServletPath();
//        if (StringUtils.isNotBlank(servletPath) && servletPath.startsWith("/api")) {
//            String newPath = servletPath.substring(4);
//            request.getRequestDispatcher(newPath).forward(request, response);
//        } else {
//            chain.doFilter(request, response);
//        }


//        StringBuffer requestURL = httpRequest.getRequestURL();
        String requestURI = httpRequest.getRequestURI();
        if(requestURI.startsWith("/test")){
            chain.doFilter(request, response);
            return;
        }
        if (pathMediaTypeMap.containsKey(requestURI)) {
            httpRequest.setAttribute(ChatgptResourceHttpRequestHandler.MEDIA_TYPE, pathMediaTypeMap.get(requestURI));
        }
        String queryString = httpRequest.getQueryString();
        String path = requestURI;

        //先前缀匹配,再精准匹配
        for (Map.Entry<String, String> stringStringEntry : rewritePathMap.entrySet()) {
            String key = stringStringEntry.getKey();
            String value = stringStringEntry.getValue();
            if (StringUtils.startsWithIgnoreCase(path,key)) {
                path = value;
            }
        }
        if (rewritePathMap.containsKey(path)) {
            path = rewritePathMap.get(path);
        }
//        if (StringUtils.equalsIgnoreCase(path, "/index")) {
//            path += ".html";
//        }
//        if (StringUtils.equalsIgnoreCase(path, "/")) {
//            path += "index.html";
//        }

//        if(StringUtils.equalsIgnoreCase(path,"/Video/GetVideoListNot")){
        //POST 参数转 url query
        if (httpRequest.getMethod().equalsIgnoreCase("POST")) {
            List<String> strings = IOUtils.readLines(httpRequest.getInputStream(), "utf-8");
            if (CollectionUtils.isNotEmpty(strings)) {
                String join = StringUtils.join(strings, "");
                JSONObject jsonObject = JsonUtil.json2Bean(join, JSONObject.class);
                queryString = jsonToQuery(jsonObject);
//                if (!StringUtils.contains(path,"?")) {
//                    path += "?";
//                }
//                path += query;
            }
        }

        if (StringUtils.isNotEmpty(queryString)) {
            path += "?";
            path += queryString;
        }

        logger.info("requestURI={},path={}",requestURI,path);

        //特殊处理写在前面
        //针对视频,匹配大小写
        if (StringUtils.startsWith(requestURI,"/video")) {
//            String name = FilenameUtils.getName(requestURI);
            String videoFilePath = videoPathMap.get(URLDecoder.decode(requestURI,"utf-8"));
            Path videoPath = Paths.get(videoFilePath);
                try {
                    MultipartFileSender.fromPath(videoPath)
                            .with(httpRequest)
                            .with(httpResponse)
                            .serveResource();
                } catch (Exception e) {
                    logger.error("get video failed", e);
                    throw new RuntimeException(e);
                }
            return;
        }else{
//            request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, path);
//            resourceHttpRequestHandler.handleRequest(httpRequest, httpResponse);
//            chain.doFilter(request,response);

        }
//        //针对index
//
//        if (StringUtils.equalsIgnoreCase(path, "/")) {
//            path = "/index.html";
//        }
//        if (StringUtils.startsWithIgnoreCase(path, "/index")) {
//            path = "/index.html";
//        }
//        if(StringUtils.equalsIgnoreCase(requestURI,"/Sys/YouDaoHtml")){
////            httpResponse.sendRedirect("https://fanyi.baidu.com/#en/zh/special");
////            fateResponseDataMap.put("/Sys/YouDaoHtml","<a href='https://fanyi.baidu.com/#en/zh/special'>https://fanyi.baidu.com/#en/zh/special</a>");
//
//            String word = request.getParameter("word");
//            StringBuffer sb= new StringBuffer();
//            for (int i = 0; i < word.length(); i++) {
//                char c = word.charAt(i);
//                if (Character.isLetter(c)) {
//                    sb.append(c);
//                }
//            }
//            word = sb.toString().toLowerCase();
//            String data = "<html><a href='https://fanyi.baidu.com/#en/zh/"+word+"' target='_blank'>百度翻译</a>";
//            ResponseRes responseRes = HttpNewUtils.get("https://dict.youdao.com/suggest?num=5&ver=3.0&doctype=json&cache=false&le=en&q="+word);
//            JSONObject object = JSONObject.parseObject(responseRes.getBodyText());
//            String formatJson = JSON.toJSONString(object.getJSONObject("data").getJSONArray("entries"), SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
//                    SerializerFeature.WriteDateUseDateFormat);
//            data += "<br/><pre>"+formatJson;
//            data += "</pre></html>";
//            httpResponse.addHeader("Content-Type", "text/html; charset=utf-8");
//            httpResponse.getOutputStream().write(data.getBytes());
//            return;
//        }
//
//
        if (fateResponseDataMap.containsKey(requestURI)) {
            ResponseBean responseBean = fateResponseDataMap.get(requestURI);
            Map<String, String> headerMap = responseBean.getHeaderMap();
            if (MapUtils.isNotEmpty(headerMap)) {
                headerMap.forEach((key,value)->{
                    httpResponse.addHeader(key, value);
                });
            }
            httpResponse.getOutputStream().write(responseBean.getBody().getBytes());
        }else{
            boolean match = false;
            for (Map.Entry<String, ResponseBean> stringResponseBeanEntry : fateResponseDataMap.entrySet()) {
                String thisUrl = stringResponseBeanEntry.getKey();
                if (StringUtils.startsWithIgnoreCase(requestURI,thisUrl)) {
                    ResponseBean responseBean = stringResponseBeanEntry.getValue();
                    Map<String, String> headerMap = responseBean.getHeaderMap();
                    if (MapUtils.isNotEmpty(headerMap)) {
                        headerMap.forEach((key,value)->{
                            httpResponse.addHeader(key, value);
                        });
                    }
                    httpResponse.getOutputStream().write(responseBean.getBody().getBytes());
                    match = true;
                }
            }
            if(!match){
                request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, path);
                resourceHttpRequestHandler.handleRequest(httpRequest, httpResponse);

            }
        }
        //放到最前面才行，不然被后面覆盖了
//        if(requestURI.startsWith("/test")){
////            chain.doFilter(request, response);
//            httpResponse.addHeader("Content-Type", "application/json; charset=utf-8");
//            httpResponse.getOutputStream().write(commonResData.getBytes());
//        }
//        StringUtils.equalsIgnoreCase(requestURI,)
//        if (StringUtils.startsWithIgnoreCase(path, "/User/Login")) {
//            httpResponse.addHeader("Content-Type", "application/json; charset=utf-8");
//            String outStr = "{\"code\":200,\"data\":{\"id\":101110,\"tele\":\"15267164682\",\"head\":\"https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83erLdnB11NtGzEq642E9JIs0ZFyNdd2xRjlicsgXZkcuqVbVrUn9tN6cbIDcG8lQIZdicfxBm5g76O0Q/132\",\"grade\":2.00,\"class\":\"会练影音·一年使用权限\",\"nickname\":\"shan\",\"name\":\"Sampson\",\"learningTime\":12335,\"isWeChat\":true,\"token\":\"43ba1c72d3f823e23fb999ee67784879b232f135\",\"serviceQrCode\":null},\"msg\":\"登录成功\",\"page\":null}";
//            httpResponse.getOutputStream().write(outStr.getBytes());
//        } else if (StringUtils.startsWithIgnoreCase(path, "/User/")) {
//            httpResponse.addHeader("Content-Type", "application/json; charset=utf-8");
//            String outStr = "{\"code\":200,\"data\":{\"id\":101110,\"tele\":\"15267164682\",\"head\":\"https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83erLdnB11NtGzEq642E9JIs0ZFyNdd2xRjlicsgXZkcuqVbVrUn9tN6cbIDcG8lQIZdicfxBm5g76O0Q/132\",\"grade\":2.00,\"class\":\"会练影音·一年使用权限\",\"nickname\":\"shan\",\"name\":\"Sampson\",\"learningTime\":12335,\"isWeChat\":true,\"token\":\"43ba1c72d3f823e23fb999ee67784879b232f135\",\"serviceQrCode\":null},\"msg\":\"登录成功\",\"page\":null}";
//            httpResponse.getOutputStream().write(outStr.getBytes());
//        } else {
//            request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, path);
////            request.setAttribute(testResourceHttpRequestHandler.ATTR_FILE, path);
//            testResourceHttpRequestHandler.handleRequest(httpRequest, httpResponse);
//        }

    }


    @Override
    public void destroy() {

    }
}

